package com.sitech.ibnms.c3p.command.shell;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import com.sitech.ibnms.c3p.Application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * Created by leo on 16/2/17.
 */
public class ShellExecutorImpl implements ShellExecutor {
    Logger logger = LoggerFactory.getLogger(getClass());

    private final Session session;

    public ShellExecutorImpl(Session session) {
        this.session = session;
    }

    @Override
    public Result execRemote(String command) {
        ChannelExec channel = null;
        try {
            //打开一个执行通道
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            channel.setOutputStream(out);
            channel.setErrStream(out);
            //将正常输出和错误输出全部是输出到ByteArrayOutputStream缓存中
            channel.connect(10 * 1000);
            while (true) {
                Thread.sleep(50);//等待断开连接
                boolean closed = channel.isClosed();
                if (closed) break;
            }
            return new Result(channel.getExitStatus(), out.toByteArray());
        } catch (Exception e) {
            throw Application.sneakyThrow(e);
        } finally {
            if (channel != null) channel.disconnect();
        }
    }

    @Override
    public Result scpToRemote(File localFile, String remoteFile) {
        ChannelSftp sftp = null;
        FileInputStream fis = null;
        try {
            sftp = (ChannelSftp) session.openChannel("sftp");
            sftp.connect(10 * 1000);

            fis = new FileInputStream(localFile);
            sftp.cd("/tmp");
            sftp.put(fis, remoteFile);
            Result result = new Result(sftp.getExitStatus(), new byte[]{});
            logger.info("sftp {} => {}", remoteFile, result.toString());
            return result;
        } catch (Exception e) {
            logger.error("Exception while sftp {}", remoteFile, e);
            throw Application.sneakyThrow(e);
        } finally {
            if (sftp != null) sftp.quit();
            if (fis != null) try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
